import { safeStringify } from "@/core";
import { TraceData } from "index";
import { compressToEncodedURIComponent } from "lz-string";

let sendErrorCount = 0;

export function sendByImg(url: string, data: TraceData) {
  return new Promise<void>((reslove, reject) => {
    if (sendErrorCount > 5) {
      console.error("The dsn is invalid.");
      sendErrorCount = 0;
      reject();
      return;
    }
    const spliceStr = url.indexOf("?") === -1 ? "?" : "&";
    const imageUrl = `${url}${spliceStr}data=${compressToEncodedURIComponent(safeStringify(data))}`;
    let img: HTMLImageElement | null = new Image();
    img.src = imageUrl;
    img.onload = function () {
      console.log("Tracking data sent successfully!");
      reslove();
      sendErrorCount = 0;
      img = null;
    };
    img.onerror = function (e: string | Event) {
      console.error("Failed to send tracking data.");
      sendErrorCount++;
      reject(e);
      img = null;
    };
  });
}

export function sendBeacon(url: string, data: TraceData) {
  if (typeof navigator === "undefined") return;
  navigator.sendBeacon && navigator.sendBeacon(url, JSON.stringify(data));
  return Promise.resolve();
}

export function sendByXHR(url: string, data: TraceData) {
  return new Promise<void>((reslove, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("post", url);
    xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    xhr.withCredentials = true;
    xhr.send(safeStringify(data));
    xhr.addEventListener("load", (e: ProgressEvent) => {
      const res = e.target as XMLHttpRequest;
      if (!(res.status >= 200 && res.status < 300)) {
        return reject(e);
      }
      reslove();
    });
  });
}

export function sendByFetch(url: string, data: TraceData) {
  return fetch(url, {
    method: "POST",
    body: JSON.stringify(data),
    headers: { "Content-Type": "application/json;charset=UTF-8" },
    credentials: "include",
  });
}
